#include "MEMSDataCodec.h"

#include "SerialPortManager.h"
#include "LogSaver.h"

MEMSDataCodec::MEMSDataCodec(QObject* parent) :QObject(parent)
{
}
MEMSDataCodec::~MEMSDataCodec()
{
	disconnect();
}
void MEMSDataCodec::slot_decode(QByteArray data) //拆解数据
{
	logSaver->saveLog(QStringLiteral("%1：收到未拆解的数据：%2").arg(objectName()).arg((QString)data.toHex()), LogSaver::Debug);
	dataBuffer.append(data);
	decode();
}
void MEMSDataCodec::decode()
{
	while ((dataBuffer.size() / dataPackageSize) > 0)
	{
		int dataPackageType = -1, groupIndex = -1;
		if (checkDataPackageHead() && checkDataPackageGroupFlag(&dataPackageType, &groupIndex) && checkDataPackageCheckSummation(dataPackageType))
		{
			QByteArray data=dataBuffer.mid(2, 14);
			logSaver->saveLog(QStringLiteral("%1：发送拆解后的数据：第%2组：%3").arg(objectName()).arg(groupIndex+1).arg((QString)data.toHex()), LogSaver::Debug);
			emit signal_feedbackData(groupIndex, data);//发送拆解后的数据
			dataBufferDropData(dataPackageSize);
		}
	}
}
bool MEMSDataCodec::checkDataPackageHead()
{
	if (dataBuffer.at(0) == (char)Head)
	{
		return true;
	}
	else
	{
		dataBufferDropData(1);
		return false;
	}
}
bool MEMSDataCodec::checkDataPackageGroupFlag()
{
	int dataPackageType, groupIndex;
	return checkDataPackageGroupFlag(&dataPackageType, &groupIndex);
}
bool MEMSDataCodec::checkDataPackageGroupFlag(int* dataPackageType, int* groupIndex)
{
	bool isValid = false;
	switch (dataBuffer.at(1))
	{
	case (char)DataFlag::SingleData:
		if (this->dataPackagetype == Multi)
		{

			isValid = false;
			break;
		}
		*dataPackageType = 0;
		*groupIndex = 0;
		isValid = true;
		break;
	case (char)DataFlag::MultiData1:
		if (this->dataPackagetype == Single)
		{
			isValid = false;
			break;
		}
		*dataPackageType = 1;
		*groupIndex = 0;
		isValid = true;
		break;
	case (char)DataFlag::MultiData2:
		if (this->dataPackagetype == Single)
		{
			isValid = false;
			break;
		}
		*dataPackageType = 1;
		*groupIndex = 1;
		isValid = true;
		break;
	case (char)DataFlag::MultiData3:
		if (this->dataPackagetype == Single)
		{
			isValid = false;
			break;
		}
		*dataPackageType = 1;
		*groupIndex = 2;
		isValid = true;
		break;
	case (char)DataFlag::MultiData4:
		if (this->dataPackagetype == Single)
		{
			isValid = false;
			break;
		}
		*dataPackageType = 1;
		*groupIndex = 3;
		isValid = true;
		break;
	case (char)DataFlag::MultiData5:
		if (this->dataPackagetype == Single)
		{
			isValid = false;
			break;
		}
		*dataPackageType = 1;
		*groupIndex = 4;
		isValid = true;
		break;
	case (char)DataFlag::MultiData6:
		if (this->dataPackagetype == Single)
		{
			isValid = false;
			break;
		}
		*dataPackageType = 1;
		*groupIndex = 5;
		isValid = true;
		break;
	default:
		isValid = false;
		break;
	}
	if (!isValid)
	{
		dataBufferDropData(1);
		*dataPackageType = -1;
		*groupIndex = -1;
	}
	return isValid;
}
bool MEMSDataCodec::checkDataPackageCheckSummation(int dataPackageType)
{
	switch (dataPackageType)
	{
	case -1:
		return false;
	case 0:
		return checkCheckSummation(2, 15);
	case 1:
		return checkCheckSummation(0, 15);
	default:
		return false;
	}
}
void MEMSDataCodec::dataBufferDropData(int byteCount)
{
	dataBuffer.remove(0, byteCount);
}
void MEMSDataCodec::addCheckSummation(QByteArray* instruction)//为输入的bytearray添加检查和
{
	int len = 16/*instruction->size()*/;
	char total = 0;
	for (int i = 0; i < len; i++) {
		char temp = instruction->at(i);
		total += temp;
	}
	instruction->append(total);
	return;
}
short MEMSDataCodec::char2ToShort(char H8, char L8)//两char转short，解析数据时使用
{
	short data1 = 0;
	data1 = ((data1 | H8) << 8) | L8;
	return data1;
}
char* MEMSDataCodec::shortToChar2(short data, char* data1)//short转两char，编码数据时使用
{
	data1[0] = data >> 8;
	data1[1] = data;
	return data1;
}
bool MEMSDataCodec::checkCheckSummation(int begin, int end)//检查检查和，检查检查和,end代表结束位置的下标和begin代表开始位置的下标
{
	char total = 0;
	for (int i = begin; i <= end; i++)
	{
		total = bitSum(total, dataBuffer.at(i));
	}
	if (total == dataBuffer.at(end + 1))
	{
		return true;
	}
	else
	{
		dataBufferDropData(dataPackageSize);
		return false;
	}
}

char MEMSDataCodec::bitSum(char x, char y)
{
	if (x == 0)
	{
		return y;
	}
	if (y == 0)
	{
		return x;
	}
	return bitSum((x ^ y), ((x & y) << 1));
}
LogSaver* MEMSDataCodec::getLogSaver()
{
	return logSaver;
}
void MEMSDataCodec::setLogSaver(LogSaver* logSaver)
{
	this->logSaver = logSaver;
}
SerialPortManager* MEMSDataCodec::getSerialPortManager()
{
	return serialPortManager;
}
void MEMSDataCodec::setSerialPortManager(SerialPortManager* serialPortManager)
{
	if (Q_NULLPTR!=this->serialPortManager)
	{
		disconnect(this->serialPortManager, &SerialPortManager::signal_dataReceived, this, &MEMSDataCodec::slot_decode);
	}
	this->serialPortManager = serialPortManager;
	connect(this->serialPortManager, &SerialPortManager::signal_dataReceived, this, &MEMSDataCodec::slot_decode, Qt::QueuedConnection);
}

MEMSDataCodec::DataPackagetype MEMSDataCodec::getDataPackagetype()
{
	return dataPackagetype;
}
void MEMSDataCodec::setDataPackagetype(DataPackagetype dataPackagetype)
{
	this->dataPackagetype = dataPackagetype;
	emit signal_currentDataPackageype(dataPackagetype);
}